﻿namespace TestingConcurrencyBenchmark.Helpers
{
    /// <summary>
    /// A counter that can be approached in a thread safe way
    /// </summary>
    public class SafeCounter
    {
        /// <summary>
        /// A mutex to protect the safecounter's critical sections
        /// </summary>
        private readonly BenchmarkSemaphore _mutex = new BenchmarkSemaphore(1);

        /// <summary>
        /// Creates a new safecounter with an initial value
        /// | new.Count == initialValue
        /// </summary>
        /// <param name="initialValue">the internal counter will be set to this value</param>
        public SafeCounter(int initialValue)
        {
            Count = initialValue;
        }

        /// <summary>
        /// Returns the internal counter's value
        /// </summary>
        public int Count { get; private set; }

        /// <summary>
        /// Adds an amount to this counter
        /// </summary>
        /// <param name="amount">The amount to add (thread safe!)</param>
        public void Add(int amount)
        {
            _mutex.WaitOne();
            Count += amount;
            _mutex.Release();
        }

        /// <summary>
        /// Subtracts an amount from this counter
        /// </summary>
        /// <param name="amount">The amount to subtract (thread safe!)</param>
        public void Subtract(int amount)
        {
            _mutex.WaitOne();
            Count -= amount;
            _mutex.Release();
        }
    }
}